package com.atguigu.zy.interview.jvm.reference;

import java.lang.ref.SoftReference;

/**
 * @author Jungle
 * @create 2022-09-04 14:31
 */
public class SoftReferenceDemo {
    /**
     * 内存够用的时候保留，内存不够用回收
     * 结果为
     * null
     * java.lang.Object@49476842
     *
     */
    public static void softRef_Memory_Enough() {
        Object o1 = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println("*****初始打印");
        System.out.println(o1);
        System.out.println(softReference.get());


        o1 = null;
        System.gc();
        System.out.println("*****o1置空后");
        System.out.println(o1);
        System.out.println(softReference.get());


    }

    /**
     * 1、了VM/配置，故意产生大对象并配置小的内存，让它内存不够用了导致oom，看软引用的回收情况
     * -Xms5m -Xmx5m -XX:+PrintGCDetails
     *
     * 结果为
     * null
     * null
     */
    public static void softRef_Memory_NotEnough() {
        Object o1 = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println("*****初始打印");
        System.out.println(o1);
        System.out.println(softReference.get());
        o1 = null;
        /**
         * 1、这里会自动gc
         */
        //System.gc();
        try {
            byte[] bytes = new byte[30 * 1024 * 1024];
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println(o1);
            System.out.println(softReference.get());
        }

    }
    /**
     * 1、应用场景 --软引用和弱引用
     * 假如有一个应用需要读取大量的本地图片:
     * *如果每次读取图片都从硬盘读取则会严重影响性能，
     * *如果一次性全部加载到内存中又可能造成内存溢出。
     *
     * 此时使用软引用可以解决这个问题。
     * 设计思路是:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系，在内存不足时，
     * JVM会自动回收这些缓存图片对象所占用的空间，从而有效地避免了OOM的问题。
     *
     * mybatis源码大量使用了软引用和弱引用
     *  HashMap<String, SoftReference<BitMap>> map = new HashMap<>();
     */
    public static void main(String[] args) {
        //softRef_Memory_Enough();
        softRef_Memory_NotEnough();

    }


}
